﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Globalization;
using System.Web;
using Peter.Sdw.Data;
using Peter.Sdw.Properties;

namespace Peter.Sdw.Logic
{
   /// <summary>
   /// View model for a header.
   /// </summary>
   public sealed class HeaderModel : BaseEditItem
   {
      private readonly ObservableCollection <Style> m_Styles;

      /// <summary>
      /// Initializes a new header.
      /// </summary>
      public HeaderModel ()
      {
         this.HasLinks = false;
         this.HasFooters = false;
         this.m_Styles = new ObservableCollection <Style> ();
      }

      /// <summary>
      /// Gets the parent id.
      /// </summary>
      public int ParentId { get; private set; }

      /// <summary>
      /// Gets the item type.
      /// </summary>
      public ItemType ItemType { get; private set; }

      /// <summary>
      /// Gets the styles for this header.
      /// </summary>
      public ObservableCollection<Style> Styles { get { return this.m_Styles; } }

      /// <summary>
      /// Gets the header data from the server.
      /// </summary>
      public void Get (ItemType type, int parentId)
      {
         this.ItemType = type;
         this.ParentId = parentId;
         WebQueue.Instance.WebGetComplete += this.OnGetCompleted;
         WebQueue.Instance.Get (string.Format (Constants.URL_GET_HEADER, this.ItemType, this.ParentId));
      }

      /// <summary>
      /// Adds the given passages to the current list.
      /// </summary>
      /// <param name="response"></param>
      public void AddStyles (dynamic response)
      {
         if (response.styles != null) {
            foreach (var style in response.styles) {
               this.Styles.Add (new Style {
                  Id = style.id,
                  Start = style.start,
                  End = style.end,
                  StartIndex = style.startindex,
                  EndIndex = style.endindex,
                  SpansMultiple = style.multispan
               });
            }
         }
      }

      /// <summary>
      /// Adds the given style.
      /// </summary>
      /// <param name="style">The style to add.</param>
      public void AddStyle (Style style)
      {
         var parameters = new NameValueCollection {
               {Constants.REQUEST_TOKEN, WebQueue.Instance.RequestToken},
               {"itemId", this.ParentId.ToString (CultureInfo.InvariantCulture)},
               {"startStyle", HttpUtility.UrlEncode (style.Start)},
               {"endStyle", HttpUtility.UrlEncode (style.End)},
               {"spansMultiple", style.SpansMultiple.ToString ()},
               {"startIndex", style.StartIndex.ToString (CultureInfo.InvariantCulture)},
               {"endIndex", style.EndIndex.ToString (CultureInfo.InvariantCulture)}
            };
         WebQueue.Instance.WebPostComplete += this.OnPostCompleted;
         WebQueue.Instance.Post (string.Format (Constants.URL_CREATE_STYLE, this.ItemType, Constants.HEADER), parameters, style);
      }

      /// <summary>
      /// Removes the given style.
      /// </summary>
      /// <param name="style">The style to remove.</param>
      public void RemoveStyle (Style style)
      {
         var parameters = new NameValueCollection {
               {Constants.REQUEST_TOKEN, WebQueue.Instance.RequestToken},
               {"id", style.Id.ToString (CultureInfo.InvariantCulture)},
               {"itemId", this.ParentId.ToString (CultureInfo.InvariantCulture)}
            };
         WebQueue.Instance.WebPostComplete += this.OnPostCompleted;
         WebQueue.Instance.Post (string.Format (Constants.URL_DELETE_STYLE, this.ItemType, Constants.HEADER), parameters);
      }

      /// <summary>
      /// Posts edits for the given style.
      /// </summary>
      /// <param name="style">The style to edit.</param>
      public void EditStyle (Style style)
      {
         var parameters = new NameValueCollection {
               {Constants.REQUEST_TOKEN, WebQueue.Instance.RequestToken},
               {"id", style.Id.ToString (CultureInfo.InvariantCulture)},
               {"itemId", this.ParentId.ToString (CultureInfo.InvariantCulture)},
               {"startStyle", HttpUtility.UrlEncode (style.Start)},
               {"endStyle", HttpUtility.UrlEncode (style.End)},
               {"spansMultiple", style.SpansMultiple.ToString ()},
               {"startIndex", style.StartIndex.ToString (CultureInfo.InvariantCulture)},
               {"endIndex", style.EndIndex.ToString (CultureInfo.InvariantCulture)}
            };
         WebQueue.Instance.WebPostComplete += this.OnPostCompleted;
         WebQueue.Instance.Post (string.Format (Constants.URL_EDIT_STYLE, this.ItemType, Constants.HEADER), parameters);
      }

      /// <summary>
      /// Occurs when a web request is completed.
      /// </summary>
      /// <param name="sender">WebQueue.</param>
      /// <param name="e">WebRequestEventArgs</param>
      private void OnGetCompleted (object sender, WebRequestEventArgs e)
      {
         try {
            if (e.Url == string.Format (Constants.URL_GET_HEADER, this.ItemType, this.ParentId)) {
               WebQueue.Instance.WebGetComplete -= this.OnGetCompleted;
               if (e.Response.status == Constants.SUCCESS) {
                  Console.WriteLine (Resources.Data_received);
                  this.AddStyles (e.Response);
               }
            }
         } catch (Exception ex) {
            Console.Error.WriteLine (ex.Message);
         }
      }

      /// <summary>
      /// Occurs when a web post request is completed.
      /// </summary>
      /// <param name="sender">WebQueue.</param>
      /// <param name="e">WebRequestEventArgs</param>
      private void OnPostCompleted (object sender, WebRequestEventArgs e)
      {
         if (e.Url == string.Format (Constants.URL_CREATE_STYLE, this.ItemType, Constants.HEADER)) {
            WebQueue.Instance.WebPostComplete -= this.OnPostCompleted;
            if (e.Response.status == Constants.SUCCESS) {
               Console.WriteLine (Resources.Data_created, Constants.HEADER);
               var style = e.Data as Style;
               if (style != null) {
                  style.Id = e.Response.id;
                  this.Styles.Add (style);
               }
            }
         } else if (e.Url == string.Format (Constants.URL_DELETE_STYLE, this.ItemType, Constants.HEADER)) {
            WebQueue.Instance.WebPostComplete -= this.OnPostCompleted;
            if (e.Response.status == Constants.SUCCESS) {
               Console.WriteLine (Resources.Data_deleted, Constants.HEADER);
               //this.Styles.Remove (this.SelectedStyle);
            }
         } else if (e.Url == string.Format (Constants.URL_EDIT_STYLE, this.ItemType, Constants.HEADER)) {
            WebQueue.Instance.WebPostComplete -= this.OnPostCompleted;
            if (e.Response.status == Constants.SUCCESS) {
               Console.WriteLine (Constants.HEADER + Resources.Edit_successful);
            }
         }
      }
   }
}
